using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.Json;
using CSharpKit.Extensions;
using CSharpKit.Native.ECCODES;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace csk.ntv.grib
{
    [TestClass]
    public class UnitTest_GRIB_keys_iterator
    {
        [TestMethod]
        public void keys_iterator()
        {
            Assert.IsFalse(false);

            var status = 0;
            var fname = "d:/sfxData/ecmwf/20200802.grib";
            var fin = eccodes.codes_fopen(fname, FileOpenModel.Read);

            // skip read only and computed keys (跳过只读和计算键)
            KeyIteratorFilter key_iterator_filter_flags = KeyIteratorFilter.CODES_KEYS_ITERATOR_SKIP_READ_ONLY
                                                      | KeyIteratorFilter.CODES_KEYS_ITERATOR_SKIP_COMPUTED
                                                      ;
            // KeyIteratorFilter key_iterator_filter_flags = KeyIteratorFilter.CODES_KEYS_ITERATOR_ALL_KEYS
            //                             | KeyIteratorFilter.CODES_KEYS_ITERATOR_SKIP_DUPLICATES
            //                             ;

            // choose a namespace.
            // name_space = NULL to get all the keys
            // e.g. "all" "ls", "time", "parameter", "geography", "statistics"
            string name_space = "all";
            // string name_space = "ls";
            // string name_space = "time";
            // string name_space = "parameter";
            // string name_space = "geography";
            // string name_space = "statistics";

            var vlen = 1024;
            var value = new byte[vlen];

            IntPtr h = IntPtr.Zero;
            int msg_count = 0;
            while ((h = eccodes.codes_handle_new_from_file(IntPtr.Zero, fin, ProductKind.GRIB, out int err)) != IntPtr.Zero)
            {
                // 消息序号
                var msgno = string.Format("GRIB N. {0:D03}", ++msg_count);
                Debug.WriteLine(string.Format("-- {0} --\n", msgno));

                // 生成键迭代器句柄
                IntPtr kiter = eccodes.codes_keys_iterator_new(h, key_iterator_filter_flags, name_space);
                if (kiter == IntPtr.Zero) break;
                Assert.IsTrue(kiter != IntPtr.Zero);

                // 迭代搜索键名和键值
                while (eccodes.codes_keys_iterator_next(kiter))
                {
                    var key_name = eccodes.codes_keys_iterator_get_name(kiter);

                    // Alternative way of getting the string value
                    var key_value1 = eccodes.codes_keys_iterator_get_string(kiter);
                    var ret = eccodes.codes_get_string(h, key_name, out string key_value2);
                    Assert.IsTrue(key_value1 == key_value2);

                    Debug.WriteLine(string.Format("{0} = {1}\n", key_name, key_value1));
                }

                // 释放键迭代器句柄
                eccodes.codes_keys_iterator_delete(kiter);


                // get values
                // 怎么知道是 double 型？
                status = eccodes.codes_get_size(h, "values", out uint values_len);
                // var values = new double[values_len * Marshal.SizeOf<double>()];
                // status = eccodes.codes_get_double_array(h, "values", values, ref values_len);

                eccodes.codes_handle_delete(h);
            }

            // 关闭文件句柄
            var stats = eccodes.codes_fclose(fin);

            Assert.IsFalse(false);
        }

        // {{END}}
    }

}